package cn.lili.modules.share.serviceimpl;

import cn.hutool.core.collection.CollUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.LockPrefix;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.modules.share.entity.docs.AppUser;
import cn.lili.modules.share.entity.dto.AppUserDTO;
import cn.lili.modules.share.entity.dto.AppUserStatistics;
import cn.lili.modules.share.mapper.AppUserMapper;
import cn.lili.modules.share.service.AppUserService;
import com.alibaba.fastjson.JSONObject;
import com.api.UserApi;
import com.api.UserShareApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pojos.OpenAppUser;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author admin
 * @since 2024-03-21
 */
@Service
@Slf4j
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements AppUserService {

    @Resource
    private RedissonClient redissonClient;
    @Resource
    private UserShareApi userShareApi;
    @Resource
    private UserApi userApi;
    @Resource
    private Cache cache;

    /**
     * 根据openid查询AppUser
     *
     * @param openId
     * @return
     */
    @Override
    public AppUser selectAppUserByOpenId(String openId) {
        LambdaQueryWrapper<AppUser> query = new LambdaQueryWrapper<>();
        query.eq(true, AppUser::getOpenid, openId);
        query.orderByDesc(AppUser::getLogin_time).orderByAsc(AppUser::getId);
        query.last("limit 1");
        return baseMapper.selectOne(query);
    }


    /**
     * 根据parentOpenId保存或更新appUser
     *
     * @param parentOpenId
     * @return
     */
    @Override
    public int updateOrSaveLowerTuiguang(String parentOpenId) {
        String INIT_KEY = LockPrefix.SHARE_BIND + "tuiguang_init_key:" + parentOpenId;
        RLock lock = redissonClient.getLock(INIT_KEY);
        try {
            lock.lock(2000, TimeUnit.MILLISECONDS);
            AppUser appUserData = this.selectAppUserByOpenId(parentOpenId);
            if (null == appUserData) {
                //新增数据
                OpenAppUser parentOpenAppUser = userShareApi.getUserinfoByOpenId(parentOpenId);
                AppUser appUser = new AppUser();
                appUser.setOpenid(parentOpenId);
                appUser.setLogin_time(Long.valueOf(System.currentTimeMillis() / 1000).intValue());
                log.info("#updateOrSaveLowerTuiguang# 保存上级信息到shrae表, 参数:{},结果:{}", parentOpenId, parentOpenAppUser != null ? JSONObject.toJSONString(parentOpenAppUser) : null);
                if (parentOpenAppUser != null) {
                    appUser.setMobile(parentOpenAppUser.getMobile());
                    appUser.setAccount(parentOpenAppUser.getNickName());
                    appUser.setGender(parentOpenAppUser.getGender());
                    appUser.setHead(parentOpenAppUser.getAvater());
                }
                appUser.setZh(appUser.getAccount());
                appUser.setTuiguang(1);
                appUser.setId(UUID.randomUUID().toString().replace("-", ""));
                baseMapper.insert(appUser);
            } else {
                //更据mobile更新appUser
                baseMapper.updateAppUserTuiguangByOpenId(parentOpenId);
            }
        } catch (Exception e) {
            log.info("#updateOrSaveLowerTuiguang# 根据parentOpenId保存或更新appUser异常:",e);
            throw new ServiceException("更新推广数量异常");
        } finally {
            lock.unlock();
        }
        return 1;
    }


    /**
     * 保存注册用户的信息
     *
     * @param openAppUser
     * @return
     */
    @Override
    public int saveAppUser(OpenAppUser openAppUser) {
        //新增数据
        AppUser appUser = new AppUser();
        OpenAppUser appUser1 = userApi.getShareOpenIdByOpenId(openAppUser.getOpenId());
        log.info("#saveAppUser# 保存注册用户的信息,参数:{},结果:{}", openAppUser.getOpenId(), (appUser1 != null ? JSONObject.toJSONString(appUser1) : null));
        appUser.setOpenid(appUser1 != null ? appUser1.getOpenId() : openAppUser.getOpenId());
        appUser.setLogin_time(Long.valueOf(System.currentTimeMillis() / 1000).intValue());
        Object parentOpenId = cache.get("shareParent" + openAppUser.getMobile());
        appUser.setSuperior(parentOpenId != null ? parentOpenId.toString() : null);
        appUser.setMobile(openAppUser.getMobile());
        appUser.setAccount(openAppUser.getNickName());
        appUser.setGender(openAppUser.getGender());
        appUser.setHead(openAppUser.getAvater());
        appUser.setZh(appUser.getAccount());
        appUser.setTuiguang(0);
        appUser.setIs_true(0);
        appUser.setId(UUID.randomUUID().toString().replace("-", ""));
        return baseMapper.insert(appUser);
    }

    /**
     * 我的邀请列表
     *
     * @return
     */
    @Override
    public Page<AppUser> myInviteList(AppUserDTO dto) {
        AuthUser authUser = UserContext.getCurrentUser();
        if (authUser == null) {
            throw new ServiceException("未登陆");
        }
        OpenAppUser appUser =userApi.getShareOpenIdByOpenId(authUser.getOpenId());
        if (appUser == null) {
            return new Page();
        }
        dto.setSuperior(appUser.getOpenId());
        Page<AppUser> page = baseMapper.selectPage(new Page(dto.getPageNumber(), dto.getPageSize(), false), dto.toQueryWrapper().select(AppUser::getHead, AppUser::getAccount, AppUser::getIs_true));
        return page;
    }


    /**
     *  我的排名
     * @param dto
     * @return
     */
    @Override
    public AppUserStatistics myRanking(AppUserDTO dto) {
        AppUserStatistics stats = new AppUserStatistics();
        AuthUser authUser = UserContext.getCurrentUser();
        if (authUser == null) {
            throw new ServiceException("未登陆");
        }
        OpenAppUser appUserShare =userApi.getShareOpenIdByOpenId(authUser.getOpenId());
        if (appUserShare == null) {
            return stats;
        }

        Page<AppUser> page = baseMapper.selectPage(new Page(dto.getPageNumber(), dto.getPageSize(), false), dto.toQueryRankingWrapper());
        if (CollUtil.isNotEmpty(page.getRecords())) {
            int index = 1;
            for (AppUser appUser : page.getRecords()) {
                appUser.setRankingNum(index);
                //我的排名
                if(appUser.getOpenid().equals(appUserShare.getOpenId())){
                    stats.setMyRankingNum(appUser.getRankingNum() != null ? appUser.getRankingNum() : 0);
                }
                index++;
            }
            stats.setAppUserList(page.getRecords());
        }
        return stats;
    }


    /**
     * 我的邀请统计
     * @param dto
     * @return
     */
    @Override
    public AppUserStatistics myInviteStatistics(AppUserDTO dto) {
        AuthUser authUser = UserContext.getCurrentUser();
        OpenAppUser appUserShare = userApi.getShareOpenIdByOpenId(authUser.getOpenId());
        if (appUserShare == null) {
            return new AppUserStatistics();
        }
        //邀请人数
        dto.setSuperior(appUserShare.getOpenId());
        Long count = baseMapper.selectCount(dto.toQueryWrapper());
        //已完成
        dto.setType(1);
        Long doneCount = baseMapper.selectCount(dto.toQueryWrapper());
        dto.setSuperior(null);
        AppUserStatistics statistics = this.myRanking(dto);
        statistics.setMyInvateNum(count.intValue());
        statistics.setIsTrueNum(doneCount.intValue());
        statistics.setAppUserList(null);
        return statistics;
    }


    /**
     * 更新用户首次购买标识
     * @param openid
     * @return
     */
    @Override
    public int updateAppUserIsTureByOpenId(String openid) {
        int result = baseMapper.updateAppUserIsTureByOpenId(openid);
        log.info("#updateAppUserIsTureByOpenId# 更新用户首次购买标识,参数:{},结果:{}", openid, result);
        return result;
    }
}
